﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Reactive.Linq;
using System.Reactive.Concurrency;
using System.Reactive.Subjects;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Reflection;

namespace ReactiveXLearning
{
    public partial class frmWindow : frmBase
    {
        IDisposable mouse_move_dis;

        public frmWindow()
        {
            InitializeComponent();
            Load += frmThrottle_Load;
            FormClosed += FrmThrottle_FormClosed;
        }

        private void frmThrottle_Load(object sender, EventArgs e)
        {
            //事件
            btn_copy.Click += Btn_copy_Click;

            MainCode();
        }

        private void MainCode()
        {

            mouse_move_dis = Observable.FromEventPattern<MouseEventArgs>(this, "MouseMove")
                .Select(h => h.EventArgs.Location)
                .Sample(TimeSpan.FromMilliseconds(200)) //鼠标移动时每 50 毫秒发送一次事件
                .Window(5) //累积到5个再一起发送
                .Subscribe(points =>
                {
                    WriteLine("开始接收一个数据组，元素包含：");
                    points.Select(x => $"X：{x.X} Y：{x.Y}").Subscribe(
                        point => WriteLine(point),
                        () => WriteLine("数据组发送完毕"));
                });
        }

        private void FrmThrottle_FormClosed(object sender, FormClosedEventArgs e)
        {
            mouse_move_dis?.Dispose();
        }

        private void Btn_copy_Click(object sender, EventArgs e)
        {
            var copys = new StringBuilder();
            var select_items = new List<object>();
            foreach (var item in lb_out.SelectedItems) select_items.Add(item);
            select_items.ToObservable()
                .Select(x => Convert.ToString(x))
                .Where(x => !string.IsNullOrWhiteSpace(x))
                .Subscribe(item => copys.AppendLine(item), () => Clipboard.SetDataObject(copys.ToString()));
        }

        private void WriteLine(object obj)
        {
            RunOnUI(() =>
            {
                lb_out.Items.Add(obj);
                lb_out.SelectedIndex = lb_out.Items.Count - 1;
            });
        }
    }
}
